#!/usr/bin/python
#
# Copyright (c) 2008, Mathias Weber
# Copyright (c) 2008, Thomas Stauffer
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
#   list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright notice,
#   this list of conditions and the following disclaimer in the documentation
#   and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# $Id: example-thread-benchmark.py 80 2008-09-24 15:53:47Z tymayos $

import sys
import time
import threading

def waste():
    sum = 0
    for i in range(100):
        for j in range(100):
            for k in range(100):
                sum += i * j * k

class Waste(threading.Thread):
    def __init__(self, iterations):
        threading.Thread.__init__(self)
        self.iterations = iterations

    def run(self):
        for i in range(self.iterations):
            print i
            waste()

if (len(sys.argv) >= 2) and (sys.argv[1] == "single"):
    try:
        iterations = int(sys.argv[2])
    except:
        iterations = 10
    print "Single", iterations

    t1 = time.time()
    for i in range(iterations):
        waste()
    t2 = time.time()

    print "Time", t2 - t1, "s"

elif (len(sys.argv) >= 2) and (sys.argv[1] == "multi"):
    try:
        iterations = int(sys.argv[2])
    except:
        iterations = 10
    try:
        threads = int(sys.argv[3])
    except:
        threads = 1
    try:
        checkinterval = int(sys.argv[4])
    except:
        checkinterval = 100 # 100 is default python checkinterval
    print "Multi", iterations, threads, checkinterval

    sys.setcheckinterval(checkinterval)
    threadlist = []
    for i in range(threads):
        threadlist += [ Waste(iterations) ]

    t1 = time.time()

    for i in range(threads):
        threadlist[i].start()

    for i in range(threads):
        threadlist[i].join()

    t2 = time.time()

    print "Time", t2 - t1, "s"

else:
    s =  sys.argv[0]
    print "Usage:"
    print " ", s, "single [iterations]"
    print " ", s, "multi [iterations] [threads] [checkinterval]"
    print
    print "Examples:"
    print " ", s,  "single 20"
    print " ", s, "multi 4 5 100"
    print " ", s, "multi 4 5 1000"
    print " ", s, "multi 4 5 1000000"

"""
Test

Python 2.5, Wintendo XP, AMD Athlon 64 X2 Dual 4200+ 2.21 GHz, 2.0 GB RAM

single 20 => 8.797 s
multi 4 5 100 => 15.484 s
multi 4 5 1000 => 9.859 s
Multi 4 5 1000000 => 8.828 s

Python 2.5, Wintendo XP, Intel Core 2 6400 2.13 GHz, 1.0 GB RAM

single 20 => 5.609 s
multi 4 5 100 => 10.0610 s
multi 4 5 1000 => 6.187 s
Multi 4 5 1000000 => 5.437 s

"""
